package com.iwhalecloud.citybrain.flow.platform.client.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/**
 * @author lilh
 * @date 2019-02-18 17:17
 */
public class GsonHelperUtils {

    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static Gson gson = new GsonBuilder().setDateFormat(DEFAULT_DATE_FORMAT).create();

    private GsonHelperUtils() {
    }

    public static JsonObject parseJson(String json) {
        JsonParser parser = new JsonParser();
        return parser.parse(json).getAsJsonObject();
    }

    public static Map<String, Object> toMap(String json) {
        return toMap(parseJson(json));
    }

    public static Map<String, Object> toMap(JsonObject json) {
        Map<String, Object> map = new HashMap<>(16);
        Set<Map.Entry<String, JsonElement>> entrySet = json.entrySet();

        for (Map.Entry<String, JsonElement> entry : entrySet) {
            String key = entry.getKey();
            JsonElement value = entry.getValue();
            if ("null".equals(value.toString())) {
                map.put(key, "");
            } else if (value instanceof JsonArray) {
                map.put(key, toList((JsonArray) value));
            } else if (value instanceof JsonObject) {
                map.put(key, toMap((JsonObject) value));
            } else {
                map.put(key, value.getAsString());
            }
        }

        return map;
    }

    public static List<Object> toList(JsonArray json) {
        List<Object> list = new ArrayList<>();

        for (int i = 0; i < json.size(); ++i) {
            JsonElement value = json.get(i);
            if (value instanceof JsonArray) {
                list.add(toList((JsonArray) value));
            } else if (value instanceof JsonObject) {
                list.add(toMap((JsonObject) value));
            } else {
                list.add(value.getAsString());
            }
        }

        return list;
    }

    public static String toJson(Object obj) {
        return gson.toJson(obj);
    }

    public static <T> T parse(String json, Class<T> clz) {
        return gson.fromJson(json, clz);
    }

    public static <T> T fromJson(JsonElement json, Class<T> classOfT) {
        return gson.fromJson(json, classOfT);
    }
}
